#include "texteditorsmanager.h"

#include <QDebug>

TextEditorsManager::TextEditorsManager(QWidget *parent) :
    QTabWidget(parent), currentEditor_(NULL)
{
    setTabsClosable(true);
    connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(onTabCloseRequested(int)));
    connect(this, SIGNAL(currentChanged(int)), SLOT(updateCurrentEditor(int)));
}

QList<TextEditor *> TextEditorsManager::editors() const
{
    QList<TextEditor *> lEditors;

    for(int i = 0; i < count(); i++) {
        lEditors.append(editor(i));
    }

    return lEditors;
}

void TextEditorsManager::newFile()
{
    TextEditor * editor = new TextEditor("");

    int index = addTab(editor, QIcon(), "untitled");
    setCurrentIndex(index);
    editor->setFocus();

    connect(editor, SIGNAL(modificationChanged(bool)), this, SLOT(onTextChanged(bool)));
}

void TextEditorsManager::openFile()
{
    QString path = QFileDialog::getOpenFileName(this, "Open file", QString(),
                   "HTML files (*.html *.htm);;Text files (*.txt)");

    if(path.isEmpty())
        return;

    TextEditor * editor = new TextEditor(path);

    QString name = path.right(path.length() - path.lastIndexOf("/") - 1);

    int index = addTab(editor, QIcon(), name);
    setCurrentIndex(index);
    editor->setFocus();

    connect(editor, SIGNAL(modificationChanged(bool)), this, SLOT(onTextChanged(bool)));
}

void TextEditorsManager::saveFile()
{
    if(currentEditor()->saveFile()) {
        QString str = currentEditor()->filename();
        setTabText(currentIndex(), str.right(str.length() - str.lastIndexOf("/") - 1));
    }
}

void TextEditorsManager::saveAs()
{
    if(currentEditor()->saveAs()) {
        QString str = currentEditor()->filename();
        setTabText(currentIndex(), str.right(str.length() - str.lastIndexOf("/") - 1));
    }
}

void TextEditorsManager::saveAll()
{
    foreach(TextEditor * te, editors()) {
        if(te->saveFile()) {
            QString str = te->filename();
            setTabText(indexOf(te), str.right(str.length() - str.lastIndexOf("/") - 1));
        }
    }
}

bool TextEditorsManager::onTabCloseRequested(int index)
{
    setCurrentIndex(index);

    QString name = tabText(index);
    name.chop(1); // remove '*'

    if(currentEditor()->document()->isModified()) {
        EditorExitDialog *exitDialog = new EditorExitDialog(name, this);
        EditorExitDialog::ExitCode exitCode = exitDialog->exec();
        delete exitDialog;

        if(exitCode == EditorExitDialog::Save) {
            currentEditor()->saveFile();
            currentEditor()->close();
        } else if(exitCode == EditorExitDialog::Discard)
            currentEditor()->close();
        else
            return false;
    }

    removeTab(currentIndex());

    if(count())
        currentWidget()->setFocus();

    return true;
}

void TextEditorsManager::onTextChanged(bool modified)
{
    if(modified)
        setTabText(currentIndex(), tabText(currentIndex()) + "*");
    else {
        QString tmp = tabText(currentIndex());
        tmp.chop(1);
        setTabText(currentIndex(), tmp);
    }
}

void TextEditorsManager::updateCurrentEditor(int index)
{
    if(currentEditor_) {
        disconnect(currentEditor_, SIGNAL(undoAvailable(bool)), this, SIGNAL(undoAvailable(bool)));
        disconnect(currentEditor_, SIGNAL(redoAvailable(bool)), this, SIGNAL(redoAvailable(bool)));
        disconnect(currentEditor_, SIGNAL(copyAvailable(bool)), this, SIGNAL(copyAvailable(bool)));
    }

    if(index >= 0)
        currentEditor_ = editor(index);
    else
        return;

    connect(currentEditor_, SIGNAL(undoAvailable(bool)), this, SIGNAL(undoAvailable(bool)));
    connect(currentEditor_, SIGNAL(redoAvailable(bool)), this, SIGNAL(redoAvailable(bool)));
    connect(currentEditor_, SIGNAL(copyAvailable(bool)), this, SIGNAL(copyAvailable(bool)));

    emit undoAvailable(currentEditor_->document()->isUndoAvailable());
    emit redoAvailable(currentEditor_->document()->isRedoAvailable());
    emit copyAvailable(currentEditor_->textCursor().hasSelection());
}
